import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.exception.ZipException;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class ZipPasswordCrackerSingle {
    public static List<String> readPasswords(String passwordFile) throws IOException {
        List<String> passwords = new ArrayList<>();
        try (BufferedReader reader = new BufferedReader(new FileReader(passwordFile))) {
            String password;
            while ((password = reader.readLine()) != null) {
                passwords.add(password);
            }
        }
        return passwords;
    }

    public static boolean tryPassword(String zipFilePath, String extractTo, String password, int attemptCount) {
        try {
            ZipFile zipFile = new ZipFile(zipFilePath);
            zipFile.setPassword(password.toCharArray());
            zipFile.extractAll(extractTo);
            System.out.println("解压成功，密码为: " + password);
            return true;
        } catch (ZipException e) {
            System.out.println("尝试第 " + attemptCount + " 次，密码错误: " + password);
        }
        return false;
    }

    public static boolean unzipFile(String zipFilePath, String extractTo, String passwordFile) throws IOException {
        List<String> passwords = readPasswords(passwordFile);

        int attemptCount = 0;
        for (String password : passwords) {
            attemptCount++;
            if (tryPassword(zipFilePath, extractTo, password, attemptCount)) {
                return true;
            }
        }

        System.out.println("所有 " + attemptCount + " 个密码均无效，解压失败");
        return false;
    }

    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();
        String zipFilePath = "./standard.zip";  // 你的加密zip文件的路径
        String extractTo = "./";  // 解压文件的目标文件夹
        String passwordFile = "./password.txt";  // 存储密码的文件路径

        try {
            unzipFile(zipFilePath, extractTo, passwordFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
        long endTime = System.currentTimeMillis();
        long duration = endTime - startTime;
        System.out.println("代码执行时间：" + duration/1000 + " 秒");
    }
}
